﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using LeadVinaglue.Models;
using LeadVinaglue.Models.ViewPages;
using LeadVinaglue.Utility;
using LeadVinaglue.Helpers;
using System.Configuration;

namespace LeadVinaglue.Repository
{
    public class LEManagementRepository : BaseRepository
    {
        LeadVinaglueEntities entities = new LeadVinaglueEntities();
        public static string ProductMediumImagesURL = ConfigurationManager.AppSettings["ProductMediumImagesURL"].ToString();
        public static int NumOfProductNotification = int.Parse(ConfigurationManager.AppSettings["NumOfProductNotification"].ToString());

        // Product Model

        public LEManagementModel GetProductUnknow(string pageType)
        {
            LEManagementModel model = new LEManagementModel();

            NavigationConfig categoryConfig = new NavigationConfig();

            // Set value
            model.Menu = GetMenuConfig(pageType);

            string CategoryCachingMenuConfig = "CategoryListConfig";
            int CategoryCachingMenuTimer = 10;
            if (HttpContext.Current.Cache[CategoryCachingMenuConfig] != null)
                categoryConfig = (NavigationConfig)HttpContext.Current.Cache[CategoryCachingMenuConfig];
            if (HttpContext.Current.Cache[CategoryCachingMenuConfig] == null)
            {
                categoryConfig = LeadTools.Deserialize(System.Web.HttpContext.Current.Server.MapPath(@"/Configs/CategoryListConfig.xml"), categoryConfig);
                HttpContext.Current.Cache.Insert(CategoryCachingMenuConfig, categoryConfig, null, DateTime.Now.AddMinutes(CategoryCachingMenuTimer), TimeSpan.Zero);
            }

            // Common
            model.ListCategory = new CategoryRepository().GetAllItems();
            model.ListSubCategory = new SubCategoryRepository().GetAllItems();
            model.ListState = new StateRepository().GetAllItems();
            
            if (pageType == LeadConstant.UNKNOW)
            {
                //model.ListCategory.RemoveAt(0);
                model.ListSubCategory.RemoveAt(0);
                //model.ListState.RemoveAt(0);
                model.ListDistrict.RemoveAt(0);
            }

            return model;
        }

        // End

        public LEManagementModel GetAllCategories(string pageType)
        {
            LEManagementModel model = new LEManagementModel();
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);

            NavigationConfig categoryConfig = new NavigationConfig();

            // Set value
            model.Menu = GetMenuConfig(pageType);

            string CategoryCachingMenuConfig = "CategoryListConfig";
            int CategoryCachingMenuTimer = 10;
            if (HttpContext.Current.Cache[CategoryCachingMenuConfig] != null)
                categoryConfig = (NavigationConfig)HttpContext.Current.Cache[CategoryCachingMenuConfig];
            if (HttpContext.Current.Cache[CategoryCachingMenuConfig] == null)
            {
                categoryConfig = LeadTools.Deserialize(System.Web.HttpContext.Current.Server.MapPath(@"/Configs/CategoryListConfig.xml"), categoryConfig);
                HttpContext.Current.Cache.Insert(CategoryCachingMenuConfig, categoryConfig, null, DateTime.Now.AddMinutes(CategoryCachingMenuTimer), TimeSpan.Zero);
            }

            model.AllCategories = categoryConfig;
            model.ProductTops = GetAllProductTop(NumOfProductNotification);
            model.AdvNotification = GetAdvNotification(NumOfProductNotification / 2);

            return model;
        }

        public LEManagementModel GetAllStates(string pageType)
        {
            LEManagementModel model = new LEManagementModel();
            NavigationConfig stateConfig = new NavigationConfig();

            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);

            // 1: State caching
            string StateCachingMenuConfig = "StateListConfig";
            int StateCachingMenuTimer = 10;
            if (HttpContext.Current.Cache[StateCachingMenuConfig] != null)
                stateConfig = (NavigationConfig)HttpContext.Current.Cache[StateCachingMenuConfig];
            if (HttpContext.Current.Cache[StateCachingMenuConfig] == null)
            {
                stateConfig = LeadTools.Deserialize(System.Web.HttpContext.Current.Server.MapPath(@"/Configs/StateListConfig.xml"), stateConfig);
                HttpContext.Current.Cache.Insert(StateCachingMenuConfig, stateConfig, null, DateTime.Now.AddMinutes(StateCachingMenuTimer), TimeSpan.Zero);
            }

            // Set value
            model.AllStates = stateConfig;
            model.ProductTops = GetAllProductTop(NumOfProductNotification);
            model.AdvNotification = GetAdvNotification(NumOfProductNotification / 2);

            return model;
        }

        public LEManagementModel GetModelBySpecials(string pageType, string url, int pageIndex, int pageSize, ref int count)
        {
            LEManagementModel model = new LEManagementModel();

            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);

            model.ProductList = GetProductListSpecials(pageIndex, pageSize, ref count);
            model.ProductTops = GetAllProductTop(NumOfProductNotification);
            model.AdvNotification = GetAdvNotification(NumOfProductNotification / 2);
            model.ResultHtml = Paginate.ResultText(count);
            model.ShowingHtml = Paginate.Showing(pageSize, pageIndex, count);
            model.PaginateHtml = Paginate.Pagination(url, pageSize, pageIndex, count);

            return model;
        }

        public LEManagementModel GetModelByCategory(string pageType, string url, int categoryId, int subId, int pageIndex, int pageSize, ref int count)
        {
            LEManagementModel model = new LEManagementModel();
            
            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);

            var cat = new CategoryRepository().GetSingle(categoryId);

            // Category Name
            if (cat != null)
            {
                model.CategoryName = cat.Name;
                model.LinkDeleted = string.Format("/raovat/c{0}/{1}", categoryId, StringClearFormat.ClearSpecials(cat.Name));
            }

            // Sub Name
            if (subId > 0)
            {
                var subCat = new SubCategoryRepository().GetSingle(subId);
                if (subCat != null)
                    model.SubCategoryName = subCat.Name;
            }
            model.SubGroupList = GetSubItem(categoryId, subId);
            model.ProductList = GetProductList(categoryId, subId, pageIndex, pageSize, ref count);
            model.ProductTops = GetAllProductTop(NumOfProductNotification);
            model.AdvNotification = GetAdvNotification(NumOfProductNotification / 2);
            model.ResultHtml = Paginate.ResultText(count);
            model.ShowingHtml = Paginate.Showing(pageSize, pageIndex, count);
            model.PaginateHtml = Paginate.Pagination(url, pageSize, pageIndex, count);

            return model;
        }

        public LEManagementModel GetModelByKeywords(string pageType, string keywords, string url, int categoryId, int subId, int pageIndex, int pageSize, ref int count)
        {
            LEManagementModel model = new LEManagementModel();
            
            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);

            var cat = new CategoryRepository().GetSingle(categoryId);

            // Category Name
            if (cat != null)
                model.CategoryName = cat.Name;

            // Sub Name
            if (subId > 0)
            {
                var subCat = new SubCategoryRepository().GetSingle(subId);
                if (subCat != null)
                    model.SubCategoryName = subCat.Name;
            }
            //model.SubGroupList = GetSubItem(categoryId, subId);
            model.ProductList = GetProductList(keywords, categoryId, subId, pageIndex, pageSize, ref count);
            model.ResultHtml = Paginate.ResultText(count);
            model.ShowingHtml = Paginate.Showing(pageSize, pageIndex, count);
            model.PaginateHtml = Paginate.Pagination(url, pageSize, pageIndex, count);

            return model;
        }

        private List<NavigationLink> GetSubItem(int categoryId, int subId)
        {
            List<NavigationLink> list = new List<NavigationLink>();

            // Get list sub category
            var subItems = new SubCategoryRepository().GetAllByCategory(categoryId, true);

            foreach (var item in subItems)
            {
                NavigationLink model = new NavigationLink();
                model.LinkText = item.Name;

                if (subId != item.ID)
                    model.LinkUrl = string.Format("/raovat/c{0}-s{1}/{2}", categoryId, item.ID, StringClearFormat.ClearSpecials(item.Name));
                else
                    model.LinkUrl = string.Empty;

                //if (subId == 0)
                    model.Count = GetCountProductByCategory(categoryId, item.ID);

                list.Add(model);
            }

            return list;
        }

        private List<ProductListModel> GetProductList(int categoryId, int subId, int pageIndex, int pageSize, ref int count)
        {
            List<ProductListModel> list = new List<ProductListModel>();

            var items = (from c in entities.Products
                         where c.Active == true && c.CategoryID== categoryId
                         select new
                         {
                             ID = c.ID,
                             ImageUrl = c.ImageURL,
                             Title = c.Title,
                             DateCreated = c.DateCreated,
                             SubCategoryId = c.SubCategoryID
                         });

            if (subId > 0)
            {
                items = items.Where(c => c.SubCategoryId == subId);
            }

            // Set value
            count = items.Count();

            // Add items
            foreach (var item in items.OrderByDescending(c => c.ID).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize))
            {
                ProductListModel model = new ProductListModel();

                model.Title = item.Title;
                if (!string.IsNullOrEmpty(item.ImageUrl))
                    model.ImageUrl = string.Format("{0}/{1}", ProductMediumImagesURL, item.ImageUrl);
                else
                    model.ImageUrl = "/images/noimagemedium.jpg";

                model.LinkUrl = string.Format("/raovat/d{0}/{1}", item.ID, StringClearFormat.ClearSpecials(item.Title));

                model.Time = Convert.ToDateTime(item.DateCreated).ToString("dd/MM/yyyy").Equals(DateTime.Now.ToString("dd/MM/yyyy")) ? "Hôm nay, " + Convert.ToDateTime(item.DateCreated).ToString("hh:mm") : Convert.ToDateTime(item.DateCreated).ToString("dd/MM/yyyy hh:mm");

                list.Add(model);
            }

            return list;
        }

        private List<ProductListModel> GetProductListSpecials(int pageIndex, int pageSize, ref int count)
        {
            List<ProductListModel> list = new List<ProductListModel>();

            var items = (from c in entities.Products
                         where c.Active == true
                         select new
                         {
                             ID = c.ID,
                             ImageUrl = c.ImageURL,
                             Title = c.Title,
                             DateCreated = c.DateCreated
                         });

            // Set value
            count = items.Count();

            // Add items
            foreach (var item in items.OrderByDescending(c => c.ID).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize))
            {
                ProductListModel model = new ProductListModel();

                model.Title = item.Title;
                if (!string.IsNullOrEmpty(item.ImageUrl))
                    model.ImageUrl = string.Format("{0}/{1}", ProductMediumImagesURL, item.ImageUrl);
                else
                    model.ImageUrl = "/images/noimagemedium.jpg";
                model.LinkUrl = string.Format("/raovat/d{0}/{1}", item.ID, StringClearFormat.ClearSpecials(item.Title));
                model.Time = Convert.ToDateTime(item.DateCreated).ToString("dd/MM/yyyy").Equals(DateTime.Now.ToString("dd/MM/yyyy")) ? "Hôm nay, " + Convert.ToDateTime(item.DateCreated).ToString("hh:mm") : Convert.ToDateTime(item.DateCreated).ToString("dd/MM/yyyy hh:mm");

                list.Add(model);
            }

            return list;
        }

        private List<ProductListModel> GetProductList(string keywords, int categoryId, int subId, int pageIndex, int pageSize, ref int count)
        {
            List<ProductListModel> list = new List<ProductListModel>();

            var items = (from c in entities.Products
                         where c.Title.Contains(keywords) && c.Active == true
                         select new
                         {
                             ID = c.ID,
                             ImageUrl = c.ImageURL,
                             Title = c.Title,
                             CategoryId = c.CategoryID,
                             DateCreated = c.DateCreated,
                             SubCategoryId = c.SubCategoryID
                         });

            if (categoryId > 0)
            {
                items = items.Where(c => c.CategoryId == categoryId);
            }

            // Set value
            count = items.Count();

            // Add items
            foreach (var item in items.OrderByDescending(c => c.ID).ToList().Skip((pageIndex - 1) * pageSize).Take(pageSize))
            {
                ProductListModel model = new ProductListModel();

                model.Title = item.Title;
                if (!string.IsNullOrEmpty(item.ImageUrl))
                    model.ImageUrl = string.Format("{0}/{1}", ProductMediumImagesURL, item.ImageUrl);
                else
                    model.ImageUrl = "/images/noimagemedium.jpg";

                model.LinkUrl = string.Format("/raovat/d{0}/{1}", item.ID, StringClearFormat.ClearSpecials(item.Title));
                model.Time = Convert.ToDateTime(item.DateCreated).ToString("dd/MM/yyyy").Equals(DateTime.Now.ToString("dd/MM/yyyy")) ? "Hôm nay, " + Convert.ToDateTime(item.DateCreated).ToString("hh:mm") : Convert.ToDateTime(item.DateCreated).ToString("dd/MM/yyyy hh:mm");

                list.Add(model);
            }

            return list;
        }

        private int GetCountProductByCategory(int categoryId, int subId)
        {
            return (from c in entities.Products
                    where c.Active == true && c.CategoryID == categoryId && c.SubCategoryID == subId
                    select c.ID).Count();
        }
        
        // Business
        public LEManagementModel GetBusinessModel(string pageType, string url, int pageIndex, int pageSize, ref int count)
        {
            LEManagementModel model = new LEManagementModel();

            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);

            model.ProductTops = GetAllProductTop(NumOfProductNotification);
            model.AdvNotification = GetAdvNotification(NumOfProductNotification / 2);
            model.ResultHtml = Paginate.ResultText(count);
            model.ShowingHtml = Paginate.Showing(pageSize, pageIndex, count);
            model.PaginateHtml = Paginate.Pagination(url, pageSize, pageIndex, count);

            return model;
        }

        // Content
        public LEManagementModel GetContentModel(string pageType, string pageName)
        {
            LEManagementModel model = new LEManagementModel();

            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            model.ArchiveTypeList = GetAllArchiveType();
            GetAdScripts(model, pageType);
            model.AppContent = new ContentRepository().GetSingle(pageName);

            return model;
        }
        public LEManagementModel GetContactModel(string pageType)
        {
            LEManagementModel model = new LEManagementModel();

            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            model.ArchiveTypeList = GetAllArchiveType();
            GetAdScripts(model, pageType);

            return model;
        }

        // Product Info
        public LEManagementModel GetProductModel(string pageType, int id)
        {
            ProductManagementRepository pmRepository=new ProductManagementRepository();
            LEManagementModel model = new LEManagementModel();

            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);
            var product = pmRepository.GetSingle(id);

            if (product != null && product.Active == true)
            {
                model.ProductInfo = product;

                // Update Review
                pmRepository.UpdateReview(id, Convert.ToInt32(model.ProductInfo.Reviewed) + 1);

                model.ProductTops = GetAllProductTop(NumOfProductNotification);
                model.AdvNotification = GetAdvNotification(NumOfProductNotification / 2);
            }

            return model;
        }

        #region Helps
        public LEManagementModel GetHelpModel(string pageType, int id)
        {
            LEManagementModel model = new LEManagementModel();

            // Set value
            model.Menu = GetMenuConfig(pageType);
            model.CategoryList = GetCategories();
            GetAdScripts(model, pageType);
            model.ArchiveTypeList = GetAllArchiveType();
            model.ArchiveInfo = GetArchive(id);

            return model;
        }

        private List<ArchiveTypeModel> GetAllArchiveType()
        {
            List<ArchiveTypeModel> list = new List<ArchiveTypeModel>();

            // Build List
            var items = (from c in entities.ArchiveTypes
                         where c.Active == true
                         select c).ToList();

            foreach (var item in items)
            {
                ArchiveTypeModel model = new ArchiveTypeModel();

                model.Name = item.Name;
                model.LinkUrl = string.Format("/help/{0}", item.ID);
                model.SubItems = GetAllArchiveBy(item.ID);

                list.Add(model);
            }


            return list;
        }
        
        private Archive GetArchive(int id)
        {
            Archive model = new Archive();
            model = new ArchiveManagementRepository().GetSingle(id);

            if (model == null)
                model = (from c in entities.Archives
                         where c.Active == true
                         select c).FirstOrDefault();


            return model;
        }

        private List<ItemLink> GetAllArchiveBy(int catId)
        {
            List<ItemLink> list = new List<ItemLink>();

            // Build List
            var items = (from c in entities.Archives
                         where c.Active == true
                         select c);

            if (catId > 0)
                items = items.Where(c => c.ArchiveTypeID == catId);

            foreach (var item in items)
            {
                ItemLink model = new ItemLink();

                model.LinkText = item.Title;
                model.LinkUrl = string.Format("/help/detail/{0}", item.ID);

                list.Add(model);
            }


            return list;
        }
        #endregion
    }
}